﻿using System;
using System.Collections;
using System.Globalization;
using System.Windows;
using System.Windows.Automation.Peers;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;

namespace Gmantis.Controls
{
    [TemplateVisualState(Name = "BottomTabStripPlacement", GroupName = "TabStripPlacementStates"), 
    TemplateVisualState(Name = "Normal", GroupName = "CommonStates"), 
    TemplateVisualState(Name = "Selected", GroupName = "SelectionStates"), 
    TemplateVisualState(Name = "Unselected", GroupName = "SelectionStates"), 
    TemplateVisualState(Name = "Disabled", GroupName = "CommonStates"), 
    TemplatePart(Name = "HeaderPresenter", Type = typeof(ContentPresenter)), 
    TemplatePart(Name = "PinButton", Type = typeof(Button)), 
    TemplatePart(Name = "UnpinButton", Type = typeof(Button)), 
    TemplatePart(Name = "StackPanelPinButtons", Type = typeof(FrameworkElement)),
    TemplatePart(Name = "CloseButton", Type = typeof(Button)), 
    TemplateVisualState(Name = "LeftTabStripPlacement", GroupName = "TabStripPlacementStates"), 
    TemplateVisualState(Name = "TopTabStripPlacement", GroupName = "TabStripPlacementStates"), 
    TemplateVisualState(Name = "RightTabStripPlacement", GroupName = "TabStripPlacementStates"), 
    TemplateVisualState(Name = "Pinned", GroupName = "PinModeStates"), 
    TemplateVisualState(Name = "Unpinned", GroupName = "PinModeStates"), 
    TemplateVisualState(Name = "MouseOver", GroupName = "CommonStates")]
    public class TabItem : ContentControl
    {
        // Fields
        internal Button _elementCloseButton;
        internal ContentPresenter _elementHeaderPresenter;
        internal Button _elementPinButton;
        internal FrameworkElement _elementStackPanelPinButtons;
        internal Button _elementUnpinButton;
        internal bool _isLoaded;
        private FrameworkElement _rootElement;
        private bool _rootIsVisible;
        internal TabControl _tabControlParent;
        private bool _throwIsMouseOverChanged;
        private bool _updatePinModeVisaul;
        internal static readonly DependencyProperty ActualPinModeProperty;
        public static readonly DependencyProperty CanUserCloseProperty;
        public static readonly DependencyProperty CanUserPinProperty;
        internal const string CloseButtonElementName = "CloseButton";
        public static readonly DependencyProperty ContentTemplateSelectorProperty;
        private static readonly DependencyProperty ContentTemplateShadowProperty;
        internal static readonly DependencyProperty ForceMouseOverProperty;
        internal const string HeaderPresenterElementName = "HeaderPresenter";
        public static readonly DependencyProperty HeaderProperty;
        public static readonly DependencyProperty HeaderTemplateProperty;
        public static readonly DependencyProperty HeaderTemplateSelectorProperty;
        private static readonly DependencyProperty IsEnabledShadowProperty;
        public static readonly DependencyProperty IsMouseOverProperty;
        public static readonly DependencyProperty IsSelectableProperty;
        public static readonly DependencyProperty IsSelectedProperty;
        internal bool IsStyleSetByTabControl;
        public static readonly DependencyProperty MouseOverBrushProperty;
        internal const string PinButtonElementName = "PinButton";
        public static readonly DependencyProperty PressedBrushProperty;
        public static readonly DependencyProperty SelectedBackgroundProperty;
        internal const string StackPanelPinButtonsElementName = "StackPanelPinButtons";
        private static readonly DependencyProperty StyleShadowProperty;
        public static readonly DependencyProperty TabShapeProperty;
        internal const string UnpinButtonElementName = "UnpinButton";
        private static readonly DependencyProperty VisibilityShadowProperty;

        // Events
        public event EventHandler<PropertyChangedEventArgs<bool>> IsMouseOverChanged;

        // Methods
        static TabItem()
        {
            HeaderProperty = DependencyProperty.Register("Header", typeof(object), typeof(TabItem), new PropertyMetadata(delegate(DependencyObject s, DependencyPropertyChangedEventArgs e)
            {
                TabItem item = (TabItem)s;
                if (item._elementHeaderPresenter != null)
                {
                    item._elementHeaderPresenter.Content = item.Header;
                }
            }));
            HeaderTemplateSelectorProperty = DependencyProperty.Register("HeaderTemplateSelector", typeof(DataTemplateSelector), typeof(TabItem), new PropertyMetadata(null));
            ContentTemplateSelectorProperty = DependencyProperty.Register("ContentTemplateSelector", typeof(DataTemplateSelector), typeof(TabItem), new PropertyMetadata(null));
            HeaderTemplateProperty = DependencyProperty.Register("HeaderTemplate", typeof(DataTemplate), typeof(TabItem), new PropertyMetadata((s, e) => ((TabItem)s).OnHeaderTemplatePropertyChanged()));
            IsSelectedProperty = DependencyProperty.Register("IsSelected", typeof(bool), typeof(TabItem), new PropertyMetadata(new PropertyChangedCallback(TabItem.OnIsSelectedChanged)));
            StyleShadowProperty = DependencyProperty.Register("StyleShadow", typeof(Style), typeof(TabItem), new PropertyMetadata(delegate(DependencyObject s, DependencyPropertyChangedEventArgs e)
            {
                TabItem tabItem = (TabItem)s;
                tabItem.IsStyleSetByTabControl = false;
                TabControl tabControlParent = tabItem.TabControlParent;
                if (tabControlParent != null)
                {
                    tabControlParent.SetItemStyle(tabItem);
                    tabControlParent.BindInheritedProperties(tabItem);
                }
            }));
            ContentTemplateShadowProperty = DependencyProperty.Register("ContentTemplateShadow", typeof(DataTemplate), typeof(TabItem), new PropertyMetadata(delegate(DependencyObject s, DependencyPropertyChangedEventArgs e)
            {
                TabItem item = (TabItem)s;
                if (item.TabControlParent != null)
                {
                    item.TabControlParent.UpdateSelectedContent();
                }
            }));
            IsEnabledShadowProperty = DependencyProperty.Register("IsEnabledShadow", typeof(bool), typeof(TabItem), new PropertyMetadata((s, e) => ((TabItem)s).OnIsReallySelectableChanged()));
            VisibilityShadowProperty = DependencyProperty.Register("VisibilityShadow", typeof(Visibility), typeof(TabItem), new PropertyMetadata((s, e) => ((TabItem)s).OnIsReallySelectableChanged()));
            TabShapeProperty = DependencyProperty.Register("TabShape", typeof(TabItemShape), typeof(TabItem), null);
            CanUserCloseProperty = DependencyProperty.Register("CanUserClose", typeof(bool), typeof(TabItem), new PropertyMetadata(true, new PropertyChangedCallback(TabItem.OnCanUserClosePropertyChanged)));
            IsSelectableProperty = DependencyProperty.Register("IsSelectable", typeof(bool), typeof(TabItem), new PropertyMetadata(true));
            ActualPinModeProperty = DependencyProperty.Register("ActualPinMode", typeof(PinMode), typeof(TabItem), new PropertyMetadata(PinMode.Unpinned, new PropertyChangedCallback(TabItem.OnActualPinModePropertyChanged)));
            CanUserPinProperty = DependencyProperty.Register("CanUserPin", typeof(bool), typeof(TabItem), new PropertyMetadata(false, new PropertyChangedCallback(TabItem.OnCanUserPinPropertyChanged)));
            IsMouseOverProperty = DependencyProperty.Register("IsMouseOver", typeof(bool), typeof(TabItem), new PropertyMetadata(new PropertyChangedCallback(TabItem.OnIsMouseOverPropertyChanged)));
            ForceMouseOverProperty = DependencyProperty.Register("ForceMouseOver", typeof(bool), typeof(TabItem), new PropertyMetadata(new PropertyChangedCallback(TabItem.OnForceMouseOverPropertyChanged)));
            MouseOverBrushProperty = DependencyProperty.Register("MouseOverBrush", typeof(Brush), typeof(TabItem), null);
            PressedBrushProperty = DependencyProperty.Register("PressedBrush", typeof(Brush), typeof(TabItem), null);
            SelectedBackgroundProperty = DependencyProperty.Register("SelectedBackground", typeof(Brush), typeof(TabItem), null);
        }

        public TabItem()
        {
            RoutedEventHandler handler = null;
            DependencyPropertyChangedEventHandler handler2 = null;
            this._rootIsVisible = true;
            this._updatePinModeVisaul = true;
            this._throwIsMouseOverChanged = true;
            base.DefaultStyleKey = typeof(TabItem);
            if (handler == null)
            {
                handler = delegate(object param0, RoutedEventArgs param1)
                {
                    this.ChangeVisualStatePinMode(false);
                    this.ChangeVisualStateCommon(false);
                };
            }
            base.Loaded += handler;
            if (handler2 == null)
            {
                handler2 = (s, a) => this.ChangeVisualStateCommon(true);
            }
            base.IsEnabledChanged += handler2;
            base.MouseEnter += new MouseEventHandler(this.Control_MouseEnter);
            base.MouseLeave += new MouseEventHandler(this.Control_MouseLeave);
            this.SetCustomDefaultValues();
        }

        private void Control_MouseEnter(object sender, MouseEventArgs e)
        {
            if (InputEventArgs.GetPointerType(e) == PointerDeviceType.Mouse)
            {
                this.IsMouseOver = true;
            }
        }

        private void Control_MouseLeave(object sender, MouseEventArgs e)
        {
            if (InputEventArgs.GetPointerType(e) == PointerDeviceType.Mouse)
            {
                this.IsMouseOver = false;
            }
        }

        internal void TabItem_LostMouseCapture(object sender, MouseEventArgs e)
        {
            base.MouseMove -= new MouseEventHandler(this.TabItem_MouseMove);
            base.LostMouseCapture -= new MouseEventHandler(this.TabItem_LostMouseCapture);
            base.MouseLeftButtonUp -= new MouseButtonEventHandler(this.TabItem_MouseLeftButtonUp);
        }

        internal void TabItem_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            base.ReleaseMouseCapture();
        }

        internal void TabItem_MouseMove(object sender, MouseEventArgs e)
        {
            Point position = e.GetPosition(null);
            TabControl tabControlParent = this.TabControlParent;
            if ((tabControlParent != null) && (this.ActualPinMode != PinMode.Pinned))
            {
                foreach (UIElement element in tabControlParent.HitTestProjectionWorkaround(position))
                {
                    this.Reorder(element, e);
                }
            }
        }

        protected void ChangeVisualStateCommon(bool useTransitions)
        {
            if (!base.IsEnabled)
            {
                VisualStateHelper.GoToState(this, "Disabled", useTransitions);
            }
            if (base.IsEnabled)
            {
                VisualStateHelper.GoToState(this, "MouseOver", useTransitions);
            }
            if ((base.IsEnabled && !this.IsMouseOver) && !this.ForceMouseOver)
            {
                VisualStateHelper.GoToState(this, "Normal", useTransitions);
            }
        }

        protected void ChangeVisualStatePinMode(bool useTransitions)
        {
            if (this.ActualPinMode == PinMode.Unpinned)
            {
                VisualStateHelper.GoToState(this, "Unpinned", useTransitions);
            }
            if (this.ActualPinMode == PinMode.Pinned)
            {
                VisualStateHelper.GoToState(this, "Pinned", useTransitions);
            }
        }

        private T GetTemplateChild<T>(string childName, bool required, ref string errors) where T : class
        {
            DependencyObject templateChild = base.GetTemplateChild(childName);
            ApplyTemplateHelper.VerifyTemplateChild(typeof(T), "template part", childName, templateChild, required, ref errors);
            return (templateChild as T);
        }

        private static Storyboard GetTemplateChildResource(FrameworkElement root, string resourceName, bool required, ref string errors)
        {
            return GetTemplateChildResource<Storyboard>(root, resourceName, required, ref errors);
        }

        private static T GetTemplateChildResource<T>(FrameworkElement root, string resourceName, bool required, ref string errors) where T : class
        {
            object child = root.Resources[resourceName];
            ApplyTemplateHelper.VerifyTemplateChild(typeof(T), "resource", resourceName, child, required, ref errors);
            return (child as T);
        }

        private void InitializeHeaderPresenterPart()
        {
            this._elementHeaderPresenter.Content = this.Header;
        }

        private void InitializePinButtonPart()
        {
            this._elementPinButton.Click += (param0, param1) => this.ActualPinMode = PinMode.Pinned;
        }

        private void InitializeStackPanelPinButtonsPart()
        {
            this.UpdateStackPanelPinButtonsVisibility();
        }

        private void InitializeUnpinButtonPart()
        {
            this._elementUnpinButton.Click += (param0, param1) => this.ActualPinMode = PinMode.Unpinned;
        }

        internal void KeyBoardNavigate(System.Windows.Input.KeyEventArgs e)
        {
            object obj2 = null;
            int direction = 0;
            int startRank = this.TabControlParent.Ranking.RankFromIndex(this.TabControlParent.IndexFromTabItem(this));
            switch (e.Key)
            {
                case Key.End:
                    direction = -1;
                    startRank = this.TabControlParent.Ranking.RankedCount;
                    break;

                case Key.Home:
                    direction = 1;
                    startRank = -1;
                    break;

                case Key.Left:
                case Key.Up:
                    direction = -1;
                    break;

                case Key.Right:
                case Key.Down:
                    direction = 1;
                    break;

                default:
                    return;
            }
            obj2 = this.TabControlParent.FindNextItem(startRank, direction);
            if ((obj2 != null) && (obj2 != this.TabControlParent.SelectedItem))
            {
                e.Handled = true;
                int num3 = this.TabControlParent.IndexFromTabItem(obj2 as TabItem);
                if ((num3 >= 0) && (num3 < this.TabControlParent.Items.Count))
                {
                    this.TabControlParent.SelectedItem = this.TabControlParent.Items[num3];
                    TabItem item = this.TabControlParent.TabItemFromItem(obj2);
                    if (item != null)
                    {
                        item.Focus();
                    }
                }
            }
        }

        private void OnActualPinModeChanged(PinMode oldValue)
        {
            if (!this._updatePinModeVisaul)
            {
                this._updatePinModeVisaul = true;
            }
            else
            {
                this.UpdateVisualState();
                this.TabControlParent.IsPinnedChanging = true;
                TabControl tabControlParent = this.TabControlParent;
                int index = tabControlParent.IndexFromTabItem(this);
                int selectedIndex = tabControlParent.SelectedIndex;
                int pinnedItemsCount = -1;
                if (this.ActualPinMode == PinMode.Pinned)
                {
                    pinnedItemsCount = tabControlParent.PinnedItemsCount;
                    if (tabControlParent.Items.IsReadOnly)
                    {
                        ObservableCollection<object> observables = new ObservableCollection<object>();
                        for (int i = 0; i < tabControlParent.Items.Count; i++)
                        {
                            observables.Add(tabControlParent.Items[i]);
                        }
                        observables.RemoveAt(index);
                        observables.Insert(pinnedItemsCount, this);
                        tabControlParent.ItemsSource = observables;
                    }
                    else
                    {
                        tabControlParent.Items.Remove(this);
                        tabControlParent.Items.Insert(pinnedItemsCount, this);
                    }
                }
                else
                {
                    pinnedItemsCount = tabControlParent.PinnedItemsCount - 1;
                    if (tabControlParent.Items.IsReadOnly)
                    {
                        int num5 = tabControlParent.IndexFromTabItem(this);
                        ObservableCollection<object> observables2 = new ObservableCollection<object>();
                        for (int j = 0; j < tabControlParent.Items.Count; j++)
                        {
                            observables2.Add(tabControlParent.Items[j]);
                        }
                        observables2.RemoveAt(num5);
                        observables2.Insert(pinnedItemsCount, this);
                        tabControlParent.ItemsSource = observables2;
                    }
                    else
                    {
                        tabControlParent.Items.Remove(this);
                        tabControlParent.Items.Insert(pinnedItemsCount, this);
                    }
                }
                bool flag = false;
                tabControlParent.UpdatePinnedItemsCount();
                if (!flag)
                {
                    int num7 = selectedIndex;
                    if (index == selectedIndex)
                    {
                        num7 = pinnedItemsCount;
                    }
                    else if (pinnedItemsCount > index)
                    {
                        if (selectedIndex <= pinnedItemsCount)
                        {
                            num7 = selectedIndex - 1;
                        }
                    }
                    else if (((index > pinnedItemsCount) && (selectedIndex >= pinnedItemsCount)) && (selectedIndex <= index))
                    {
                        num7 = selectedIndex + 1;
                    }
                    tabControlParent.SelectedIndex = num7;
                    if (tabControlParent.SelectedItem != null)
                    {
                        TabItem selectedItem = null;
                        if (tabControlParent.SelectedItem is TabItem)
                        {
                            selectedItem = tabControlParent.SelectedItem as TabItem;
                        }
                        else
                        {
                            selectedItem = tabControlParent.TabItemFromItem(tabControlParent.SelectedItem);
                        }
                        selectedItem.Focus();
                    }
                    tabControlParent.IsPinnedChanging = false;
                    if (num7 != selectedIndex)
                    {
                        tabControlParent.OnSelectionChanged(index);
                    }
                }
            }
        }

        private static void OnActualPinModePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            TabItem item = d as TabItem;
            PinMode oldValue = (PinMode)e.OldValue;
            item.OnActualPinModeChanged(oldValue);
            item.ChangeVisualStatePinMode(true);
        }

        private void OnAfterApplyTemplate()
        {
            RoutedEventHandler handler = null;
            this.UpdateVisualState();
            this.UpdateCloseButton();
            if (this._elementCloseButton != null)
            {
                if (handler == null)
                {
                    handler = delegate(object s, RoutedEventArgs a)
                    {
                        TabControl tabControlParent = this.TabControlParent;
                        if (tabControlParent != null)
                        {
                            tabControlParent.OnTabItemClosing(tabControlParent.IndexFromTabItem(this));
                        }
                    };
                }
                this._elementCloseButton.Click += handler;
            }
        }

        public override void OnApplyTemplate()
        {
            this.OnBeforeApplyTemplate();
            string errors = string.Empty;
            base.OnApplyTemplate();
            this._isLoaded = true;
            this._elementCloseButton = this.GetTemplateChild<Button>("CloseButton", false, ref errors);
            this._elementHeaderPresenter = this.GetTemplateChild<ContentPresenter>("HeaderPresenter", false, ref errors);
            if (this._elementHeaderPresenter != null)
            {
                this.InitializeHeaderPresenterPart();
            }
            this._elementPinButton = this.GetTemplateChild<Button>("PinButton", false, ref errors);
            if (this._elementPinButton != null)
            {
                this.InitializePinButtonPart();
            }
            this._elementUnpinButton = this.GetTemplateChild<Button>("UnpinButton", false, ref errors);
            if (this._elementUnpinButton != null)
            {
                this.InitializeUnpinButtonPart();
            }
            this._elementStackPanelPinButtons = this.GetTemplateChild<FrameworkElement>("StackPanelPinButtons", false, ref errors);
            if (this._elementStackPanelPinButtons != null)
            {
                this.InitializeStackPanelPinButtonsPart();
            }
            if (!string.IsNullOrEmpty(errors))
            {
                this._isLoaded = false;
                if ((base.Template != null) && !PlatformIndependent.IsInDesignMode(this))
                {
                    throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, "Template cannot be applied to TabItem.\nDetails: {0}", new object[] { errors }));
                }
            }
            else
            {
                this.ChangeVisualStatePinMode(false);
                this.ChangeVisualStateCommon(false);
                this.OnAfterApplyTemplate();
            }
        }

        private void OnBeforeApplyTemplate()
        {
            if (this._elementHeaderPresenter != null)
            {
                this._elementHeaderPresenter.Content = null;
            }
            this._rootElement = VisualTreeHelper.GetChild(this, 0) as FrameworkElement;
            if (this._rootElement != null)
            {
                this._rootElement.Visibility = this._rootIsVisible ? Visibility.Visible : Visibility.Collapsed;
            }
        }

        private void OnCanUserCloseChanged(bool oldValue)
        {
            this.UpdateCloseButton();
        }

        private static void OnCanUserClosePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            TabItem item = d as TabItem;
            bool oldValue = (bool)e.OldValue;
            item.OnCanUserCloseChanged(oldValue);
        }

        private void OnCanUserPinChanged(bool oldValue)
        {
            this.UpdateStackPanelPinButtonsVisibility();
        }

        private static void OnCanUserPinPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            TabItem item = d as TabItem;
            bool oldValue = (bool)e.OldValue;
            item.OnCanUserPinChanged(oldValue);
        }

        protected override void OnContentChanged(object oldContent, object newContent)
        {
            base.OnContentChanged(oldContent, newContent);
            if (this.TabControlParent != null)
            {
                this.TabControlParent.UpdateSelectedContent();
            }
        }

        protected override AutomationPeer OnCreateAutomationPeer()
        {
            return new TabItemAutomationPeer(this);
        }

        private static void OnForceMouseOverPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            (d as TabItem).ChangeVisualStateCommon(true);
        }

        internal virtual void OnHeaderTemplatePropertyChanged()
        {
        }

        private static void OnIsMouseOverPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            TabItem sender = d as TabItem;
            if ((sender.IsMouseOverChanged != null) && sender._throwIsMouseOverChanged)
            {
                PropertyChangedEventArgs<bool> args = new PropertyChangedEventArgs<bool>
                {
                    OldValue = (bool)e.OldValue,
                    NewValue = (bool)e.NewValue
                };
                sender.IsMouseOverChanged(sender, args);
            }
            sender.ChangeVisualStateCommon(true);
        }

        private void OnIsReallySelectableChanged()
        {
            TabControl tabControlParent = this.TabControlParent;
            if (tabControlParent != null)
            {
                tabControlParent.UpdateSelection();
                if (tabControlParent._elementMenu != null)
                {
                    int num = tabControlParent.Ranking.RankFromIndex(tabControlParent.IndexFromTabItem(this));
                    if ((num != -1) && (num < tabControlParent._elementMenu.Items.Count))
                    {
                        (tabControlParent._elementMenu.Items[num] as MenuItem).Visibility = this.IsReallySelectable.ToVisibility();
                    }
                }
            }
        }

        private static void OnIsSelectedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            TabItem item = (TabItem)d;
            bool newValue = (bool)e.NewValue;
            RoutedEventArgs args = new RoutedEventArgs();
            if (newValue)
            {
                item.OnSelected(args);
            }
            else
            {
                item.OnUnselected(args);
            }
            item.IsTabStop = newValue;
            item.UpdateVisualState();
        }

        protected override void OnKeyDown(System.Windows.Input.KeyEventArgs e)
        {
            base.OnKeyDown(e);
            if (!e.Handled && (this.TabControlParent != null))
            {
                this.KeyBoardNavigate(e);
            }
        }

        protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
        {
            base.OnMouseLeftButtonDown(e);
            if ((this.IsReallySelectable && (this.TabControlParent != null)) && !e.Handled)
            {
                this.IsSelected = true;
                base.IsTabStop = true;
                e.Handled = base.Focus();
                if (this.TabControlParent.CanUserReorder && this.TryCaptureMouse())
                {
                    base.MouseMove += new MouseEventHandler(this.TabItem_MouseMove);
                    base.LostMouseCapture += new MouseEventHandler(this.TabItem_LostMouseCapture);
                    base.MouseLeftButtonUp += new MouseButtonEventHandler(this.TabItem_MouseLeftButtonUp);
                }
            }
        }

        protected virtual void OnSelected(RoutedEventArgs e)
        {
            if (!this.IsReallySelectable)
            {
                this.IsSelected = false;
            }
            else if (this.TabControlParent != null)
            {
                this.TabControlParent.SelectedIndex = this.TabControlParent.IndexFromTabItem(this);
            }
        }

        protected virtual void OnUnselected(RoutedEventArgs e)
        {
            if ((this.TabControlParent != null) && (this.TabControlParent.SelectedItem == this))
            {
                this.TabControlParent.SelectedIndex = -1;
            }
        }

        private static void Orphan(FrameworkElement element)
        {
            ItemsControl control;
        Label_0000:
            control = element.Parent as ItemsControl;
            if (control != null)
            {
                control.Items.Remove(element);
                if ((control.Items.Count <= 0) && (control.Name.Length <= 0))
                {
                    element = control;
                    goto Label_0000;
                }
            }
        }

        internal void Reorder(UIElement element, MouseEventArgs e)
        {
            TabItem relativeTo = element as TabItem;
            TabControl tabControlParent = this.TabControlParent;
            if (((((tabControlParent != null) && (relativeTo != null)) && (relativeTo != this)) && (relativeTo.TabControlParent == tabControlParent)) && (relativeTo.ActualPinMode != PinMode.Pinned))
            {
                IList list = tabControlParent.SourceList();
                Orientation orientation = tabControlParent.ActualTabStripPlacement.GetOrientation().Opposite();
                Point position = e.GetPosition(relativeTo);
                Size size = this.ActualSize();
                Size size2 = relativeTo.ActualSize();
                if ((size.Width != 0.0) || (size.Height != 0.0))
                {
                    int oldIndex = tabControlParent.IndexFromTabItem(this);
                    object obj2 = tabControlParent.Items[oldIndex];
                    int num2 = tabControlParent.IndexFromTabItem(relativeTo);
                    double width = size.Width;
                    double height = size2.Width;
                    double x = position.X;
                    if (orientation == Orientation.Vertical)
                    {
                        width = size.Height;
                        height = size2.Height;
                        x = position.Y;
                    }
                    int newIndex = num2;
                    if (oldIndex < num2)
                    {
                        if (width < (height - x))
                        {
                            newIndex = num2 - 1;
                        }
                    }
                    else if (width <= x)
                    {
                        newIndex = num2 + 1;
                    }
                    if (list == null)
                    {
                        tabControlParent.VirtualMove(oldIndex, newIndex);
                        tabControlParent._elementTabPanel.InvalidateMeasure();
                        tabControlParent.UpdateMenuItems();
                    }
                    else
                    {
                        if (obj2 != this)
                        {
                            base.ReleaseMouseCapture();
                            tabControlParent.TryCaptureMouse();
                        }
                        tabControlParent.reordering = true;
                        list.Remove(obj2);
                        if (obj2 != this)
                        {
                            tabControlParent.IndexToRecapture = newIndex;
                        }
                        list.Insert(newIndex, obj2);
                        tabControlParent.SelectedIndex = newIndex;
                        tabControlParent.reordering = false;
                    }
                }
            }
        }

        private void SetCustomDefaultValues()
        {
            base.SetBinding(StyleShadowProperty, new Binding().From<TabItem>(this, x => x.Style));
            base.SetBinding(ContentTemplateShadowProperty, new Binding().From<TabItem>(this, x => x.ContentTemplate));
            base.SetBinding(IsEnabledShadowProperty, new Binding().From<TabItem>(this, x => x.IsEnabled));
            base.SetBinding(VisibilityShadowProperty, new Binding().From<TabItem>(this, x => x.Visibility));
        }

        internal void UpdateCloseButton()
        {
            if ((this.TabControlParent != null) && (this._elementCloseButton != null))
            {
                if ((this.TabControlParent.TabItemClose == TabItemCloseOptions.InEachTab) && this.CanUserClose)
                {
                    this._elementCloseButton.Visibility = Visibility.Visible;
                }
                else
                {
                    this._elementCloseButton.Visibility = Visibility.Collapsed;
                }
            }
        }

        internal void UpdateStackPanelPinButtonsVisibility()
        {
            if ((this.TabControlParent != null) && (this._elementStackPanelPinButtons != null))
            {
                if (this.CanUserPin)
                {
                    this._elementStackPanelPinButtons.Visibility = Visibility.Visible;
                }
                else
                {
                    this._elementStackPanelPinButtons.Visibility = Visibility.Collapsed;
                }
            }
        }

        internal virtual void UpdateVisualState()
        {
            if (this.IsSelected)
            {
                VisualStateManager.GoToState(this, "Selected", false);
            }
            else
            {
                VisualStateManager.GoToState(this, "Unselected", false);
            }
            VisualStateManager.GoToState(this, this.ActualTabStripPlacement + "TabStripPlacement", false);
            VisualStateManager.GoToState(this, this.ActualPinMode + "PinMode", false);
        }

        // Properties
        internal PinMode ActualPinMode
        {
            get { return (PinMode)GetValue(ActualPinModeProperty); }
            set { SetValue(ActualPinModeProperty, value); }
        }

        private Dock ActualTabStripPlacement
        {
            get
            {
                if (this.TabControlParent == null)
                {
                    return Dock.Left;
                }
                return this.TabControlParent.ActualTabStripPlacement;
            }
        }

        public bool CanUserClose
        {
            get { return (bool)GetValue(CanUserCloseProperty); }
            set { SetValue(CanUserCloseProperty, value); }
        }

        public bool CanUserPin
        {
            get { return (bool)GetValue(CanUserPinProperty); }
            set { SetValue(CanUserPinProperty, value); }
        }

        public DataTemplateSelector ContentTemplateSelector
        {
            get { return (DataTemplateSelector)GetValue(ContentTemplateSelectorProperty); }
            set { SetValue(ContentTemplateSelectorProperty, value); }
        }

        internal bool ForceMouseOver
        {
            get { return (bool)GetValue(ForceMouseOverProperty); }
            set { SetValue(ForceMouseOverProperty, value); }
        }

        public object Header
        {
            get { return GetValue(HeaderProperty); }
            set { SetValue(HeaderProperty, value); }
        }

        public DataTemplate HeaderTemplate
        {
            get { return (DataTemplate)GetValue(HeaderTemplateProperty); }
            set { SetValue(HeaderTemplateProperty, value); }
        }

        public DataTemplateSelector HeaderTemplateSelector
        {
            get { return (DataTemplateSelector)GetValue(HeaderTemplateSelectorProperty); }
            set { SetValue(HeaderTemplateSelectorProperty, value); }
        }

        public bool IsMouseOver
        {
            get { return (bool)GetValue(IsMouseOverProperty); }
            internal set { SetValue(IsMouseOverProperty, value); }
        }

        internal bool IsReallySelectable
        {
            get
            {
                if (!this.IsSelectable)
                {
                    return false;
                }
                if (base.Visibility != Visibility.Visible)
                {
                    return false;
                }
                if (((this.TabControlParent != null) && this.TabControlParent.IsEnabled) && !base.IsEnabled)
                {
                    return false;
                }
                return true;
            }
        }

        public bool IsSelectable
        {
            get { return (bool)GetValue(IsSelectableProperty); }
            set { SetValue(IsSelectableProperty, value); }
        }

        public bool IsSelected
        {
            get { return (bool)GetValue(IsSelectedProperty); }
            set { SetValue(IsSelectedProperty, value); }
        }

        public Brush MouseOverBrush
        {
            get { return (Brush)GetValue(MouseOverBrushProperty); }
            set { SetValue(MouseOverBrushProperty, value); }
        }

        public Brush PressedBrush
        {
            get { return (Brush)GetValue(PressedBrushProperty); }
            set { SetValue(PressedBrushProperty, value); }
        }

        internal bool RootIsVisible
        {
            get
            {
                bool flag = true;
                if (this._rootElement != null)
                {
                    flag = this._rootElement.Visibility == Visibility.Visible;
                }
                return flag;
            }
            set
            {
                this._rootIsVisible = value;
                if (this._rootElement != null)
                {
                    this._rootElement.Visibility = this._rootIsVisible ? Visibility.Visible : Visibility.Collapsed;
                }
            }
        }

        public Brush SelectedBackground
        {
            get { return (Brush)GetValue(SelectedBackgroundProperty); }
            set { SetValue(SelectedBackgroundProperty, value); }
        }

        internal TabControl TabControlParent
        {
            get
            {
                if (base.Parent is TabControl)
                {
                    return (base.Parent as TabControl);
                }
                if (this._tabControlParent == null)
                {
                    return null;
                }
                return this._tabControlParent;
            }
        }

        public TabItemShape TabShape
        {
            get { return (TabItemShape)GetValue(TabShapeProperty); }
            set { SetValue(TabShapeProperty, value); }
        }
    }

    public enum PinMode
    {
        Unpinned,
        Pinned
    }

    public enum TabItemCloseOptions
    {
        None,
        InEachTab,
        GlobalClose
    }
}
